#include "cgzCLua.h"

struct tagNode
{
    long id;
    long ms;
    // 添加构造函数便于创建对象
    tagNode(long i = 0, long m = 0) : id(i), ms(m) {}
};

// 比较函数类型定义
using compareF = std::function<bool(const tagNode &, const tagNode &)>;

// 定时器组结构
struct tagMSet
{
    compareF comp;                   // 比较函数
    std::set<tagNode, compareF> set; // 使用自定义比较函数的集合

    // 构造函数，接受比较函数
    tagMSet(compareF compFunc)
        : comp(compFunc), set(compFunc) {}
};

// 管理多个定时器组
using MapTimer = std::map<long, tagMSet>;
static MapTimer mapTimer;

static long cid_counter = 0; // 全局计数器
static const compareF casc = [](const tagNode &a, const tagNode &b)
{
    return (a.ms != b.ms ? a.ms < b.ms : a.id < b.id);
};
static const compareF desc = [](const tagNode &a, const tagNode &b)
{
    return (a.ms != b.ms ? a.ms > b.ms : a.id > b.id);
};

static int mset_create(lua_State *L)
{
    // 获取排序方向参数
    if (lua_gettop(L) < 1)
    {
        luaL_error(L, "mset_create requires 1 argument (isDescending)");
        return 0;
    }

    bool isDescending = lua_toboolean(L, 1);
    // 创建新的定时器组
    long new_cid = ++cid_counter;
    if (isDescending)
    {
        mapTimer.emplace(new_cid, tagMSet(desc));
    }
    else
    {
        mapTimer.emplace(new_cid, tagMSet(casc));
    }
    // 返回新的cid给Lua
    lua_pushinteger(L, new_cid);
    return 1; // 返回一个值
}

static int mset_insert(lua_State *L)
{
    // 参数检查: 需要3个参数(cid, id, ms)
    if (lua_gettop(L) < 3)
    {
        luaL_error(L, "mset_insert requires 3 arguments (cid, id, ms)");
        return 0;
    }

    long cid = lua_tointeger(L, 1);
    long id = lua_tointeger(L, 2);
    long ms = lua_tointeger(L, 3);

    // 查找对应的定时器组
    auto it_cid = mapTimer.find(cid);
    if (it_cid == mapTimer.end())
    {
        luaL_error(L, "Invalid timer group id: %d", cid);
        return 0;
    }

    auto &group = it_cid->second;
    auto &setGroup = group.set;

    // 查找并移除同id的旧记录（如果存在）
    for (auto it = setGroup.begin(); it != setGroup.end(); ++it)
    {
        if (it->id == id)
        {
            setGroup.erase(it);
            break;
        }
    }

    // 插入新节点
    setGroup.insert(tagNode(id, ms));

    return 0;
}

static int mset_delete(lua_State *L)
{
    // 参数检查: 需要2个参数(cid, id ,ms)
    int top = lua_gettop(L);
    if (top < 3)
    {
        luaL_error(L, "mset_delete requires 3 arguments (cid, id, ms)");
        return 0;
    }

    long cid = lua_tointeger(L, 1);
    long id = lua_tointeger(L, 2);
    long ms = lua_tointeger(L, 2);
    ;

    // 查找对应的定时器组
    auto it_cid = mapTimer.find(cid);
    if (it_cid == mapTimer.end())
    {
        luaL_error(L, "Invalid timer group id: %d", cid);
        return 0;
    }

    auto &setGroup = it_cid->second.set;
    auto it_key = setGroup.find(tagNode(id, ms));
    if (it_key != setGroup.end())
    {
        setGroup.erase(it_key);
    }
    else
    {
        // 查找并删除节点
        for (auto it = setGroup.begin(); it != setGroup.end(); ++it)
        {
            if (it->id == id)
            {
                setGroup.erase(it);
                break;
            }
        }
    }

    return 0;
}

static int mset_clear(lua_State *L)
{
    // 参数检查: 需要1个参数(cid)
    if (lua_gettop(L) < 1)
    {
        luaL_error(L, "mset_clear requires 1 argument (cid)");
        return 0;
    }

    long cid = lua_tointeger(L, 1);

    // 查找对应的定时器组
    auto it_cid = mapTimer.find(cid);
    if (it_cid == mapTimer.end())
    {
        luaL_error(L, "Invalid timer group id: %d", cid);
        return 0;
    }

    // 清空定时器组
    it_cid->second.set.clear();

    return 0;
}

static int mset_begin(lua_State *L)
{
    // 参数检查: 需要1个参数(cid)
    if (lua_gettop(L) < 1)
    {
        luaL_error(L, "mset_begin requires 1 argument (cid)");
        return 0;
    }

    long cid = lua_tointeger(L, 1);

    // 查找对应的定时器组
    auto it_cid = mapTimer.find(cid);
    if (it_cid == mapTimer.end())
    {
        luaL_error(L, "Invalid timer group id: %d", cid);
        return 0;
    }

    auto &setGroup = it_cid->second.set;

    // 返回最小节点
    if (setGroup.empty())
    {
        return 0; // 空集合返回0个结果
    }
    else
    {
        auto it = setGroup.begin(); // 最小节点
        lua_pushinteger(L, it->id); // id
        lua_pushinteger(L, it->ms); // ms
        return 2;                   // 返回两个值
    }
}

static int mset_end(lua_State *L)
{
    // 参数检查: 需要1个参数(cid)
    if (lua_gettop(L) < 1)
    {
        luaL_error(L, "mset_end requires 1 argument (cid)");
        return 0;
    }

    long cid = lua_tointeger(L, 1);

    // 查找对应的定时器组
    auto it_cid = mapTimer.find(cid);
    if (it_cid == mapTimer.end())
    {
        luaL_error(L, "Invalid timer group id: %d", cid);
        return 0;
    }

    auto &setGroup = it_cid->second.set;

    // 返回最大节点
    if (setGroup.empty())
    {
        return 0; // 空集合返回0个结果
    }
    else
    {
        auto it = std::prev(setGroup.end()); // 最大节点
        lua_pushinteger(L, it->id);          // id
        lua_pushinteger(L, it->ms);          // ms
        return 2;                            // 返回两个值
    }
}

static int mset_next(lua_State *L)
{
    // 参数检查: 需要2个参数(cid, id)
    if (lua_gettop(L) < 2)
    {
        luaL_error(L, "mset_next requires 2 arguments (cid, id)");
        return 0;
    }

    long cid = lua_tointeger(L, 1);
    long id = lua_tointeger(L, 2);

    // 查找对应的定时器组
    auto it_cid = mapTimer.find(cid);
    if (it_cid == mapTimer.end())
    {
        luaL_error(L, "Invalid timer group id: %d", cid);
        return 0;
    }

    auto &setGroup = it_cid->second.set;

    // 查找当前节点
    auto current = setGroup.end();
    for (auto it = setGroup.begin(); it != setGroup.end(); ++it)
    {
        if (it->id == id)
        {
            current = it;
            break;
        }
    }

    if (current == setGroup.end())
    {
        return 0; // 未找到当前节点
    }

    // 获取下一个节点
    auto next = std::next(current);
    if (next == setGroup.end())
    {
        return 0; // 没有下一个节点
    }

    // 返回下一个节点
    lua_pushinteger(L, next->id); // id
    lua_pushinteger(L, next->ms); // ms
    return 2;                     // 返回两个值
}

static int mset_destroy(lua_State *L)
{
    // 参数检查: 需要1个参数(cid)
    if (lua_gettop(L) < 1)
    {
        luaL_error(L, "mset_destroy requires 1 argument (cid)");
        return 0;
    }

    long cid = lua_tointeger(L, 1);

    // 查找并删除定时器组
    auto it = mapTimer.find(cid);
    if (it != mapTimer.end())
    {
        mapTimer.erase(it);
    }

    return 0;
}

int cgzCLua::luaopen_mset(lua_State *L)
{
    const luaL_Reg libs[] = {
        {"create", mset_create},
        {"insert", mset_insert},
        {"delete", mset_delete},
        {"clear", mset_clear},
        {"begin", mset_begin},
        {"end", mset_end},
        {"next", mset_next},
        {"destroy", mset_destroy},
        {NULL, NULL}};

    luaL_newlib(L, libs);
    return 1;
}